'use client';

import { useRef, useEffect, useState } from "react";
import { DRAG_MODE, Niivue } from "@niivue/niivue";

// 最终修正版 3D 查看器
function SingleViewer3D({ imageUrl, imageName, maskUrls = [] }) {
    const canvasRef = useRef(null);
    const nvRef = useRef(null);
    const [isLoading, setIsLoading] = useState(true);
    const [error, setError] = useState(null);

    // 切片位置 State - 显示当前各个方向的切片索引
    const [sliceIndices, setSliceIndices] = useState({
        axial: 0,    // 轴向切片索引
        sagittal: 0, // 矢状切片索引
        coronal: 0   // 冠状切片索引
    });

    // 灰度调节 State
    const [dataRange, setDataRange] = useState({ min: 0, max: 1000 });
    const [intensityMin, setIntensityMin] = useState(0);
    const [intensityMax, setIntensityMax] = useState(1000);

    // 滚轮控制 State (true = 缩放, false = 切片)
    const [useWheelForZoom, setUseWheelForZoom] = useState(false);

    // 3D 渲染模式 State
    const [renderMode, setRenderMode] = useState('multiplanar'); // 'multiplanar' 或 '3d'

    // Mask 透明度 State
    const [maskOpacity, setMaskOpacity] = useState(0.7);

    // Effect 1: 加载和初始化Niivue
    useEffect(() => {
        console.log('ImageViewer3D - useEffect 触发，imageUrl:', imageUrl, 'maskUrls:', maskUrls);

        if (!imageUrl) {
            setIsLoading(false);
            return;
        }

        setIsLoading(true);
        setError(null);

        const handleContextMenu = (e) => e.preventDefault();

        async function setupNiivue() {
            try {
                const canvas = canvasRef.current;
                if (!canvas) throw new Error("Canvas element not found");


                const nv = new Niivue();
                nvRef.current = nv;
                nv.attachToCanvas(canvas);
                console.log('ImageViewer3D - Niivue 实例已附加到 canvas');

                // --- 新增代码：修改右键拖拽行为 ---
                // 获取并打印所有可用的colormap
                const availableColormaps = nv.colormaps();
                console.log('Available colormaps:', availableColormaps);


                // 设置初始视图为多平面
                nv.setSliceType(nv.sliceTypeMultiplanar);
                // 将右键拖拽的默认功能从 'zoom' (缩放) 修改为 'pan' (平移)

                canvas.addEventListener('contextmenu', handleContextMenu);
                // // 绑定事件，禁用默认的浏览器右键菜单
                // nv.setTouchEventConfig({
                //     singleTouch: DRAG_MODE.windowing,
                //     doubleTouch: DRAG_MODE.pan,
                // });                
                nv.opts.fontColor = [0, 1, 0, 1]; // 绿色字体
                nv.setShowAllOrientationMarkers(true);


                // 加载原始图像
                const volumesToLoad = [{ url: imageUrl }];

                // 加载所有mask
                if (maskUrls && Array.isArray(maskUrls) && maskUrls.length > 0) {
                    console.log('ImageViewer3D - 准备加载 mask URLs:', maskUrls);
                    maskUrls.forEach((item, index) => {
                        // 支持字符串或对象形式的 mask 描述
                        const maskUrl = typeof item === 'string' ? item : item.url;
                        const opacity = typeof item === 'object' ? item.opacity : 0.7;
                        // 确保颜色映射只使用内建的 'red', 'green', 'blue' 三种模式
                        const providedColorMap = typeof item === 'object' ? item.colorMap : 'red';
                        const colorMap = ['red', 'green', 'blue'].includes(providedColorMap) ? providedColorMap : 'red';

                        // 确保URL是完整的
                        const fullMaskUrl = maskUrl.startsWith('http') ? maskUrl :
                            `http://10.69.64.129:8000/api/${maskUrl}`;
                        console.log(`ImageViewer3D - 添加 mask ${index + 1}:`, fullMaskUrl, 'opacity:', opacity, 'colorMap:', colorMap);
                        volumesToLoad.push({
                            url: fullMaskUrl,
                            opacity: opacity,
                            colorMap: colorMap,
                            cal_min: 0.1,
                            cal_max: 1.0,
                            visible: true,
                            renderShader: 'mip'
                        });
                    });
                } else {
                    console.log('ImageViewer3D - 没有有效的 mask URLs 需要加载');
                }

                console.log('ImageViewer3D - 最终要加载的 volumes:', volumesToLoad);

                // 先清理现有的 volumes
                if (nv.volumes && nv.volumes.length > 0) {
                    console.log('ImageViewer3D - 清理现有的', nv.volumes.length, '个 volumes');
                    nv.clearVolumes();
                }

                try {
                    console.log('ImageViewer3D - 开始加载 volumes:', volumesToLoad);
                    await nv.loadVolumes(volumesToLoad);
                    console.log('ImageViewer3D - 成功加载 volumes，数量:', nv.volumes.length);

                    // 检查每个 volume 的加载状态
                    nv.volumes.forEach((volume, index) => {
                        console.log(`ImageViewer3D - Volume ${index}:`, {
                            url: volume.url,
                            dims: volume.dims,
                            loaded: volume.img ? 'Yes' : 'No',
                            error: volume.error || 'None'
                        });
                    });
                } catch (loadError) {
                    console.error('ImageViewer3D - 加载 volumes 失败:', loadError);
                    // 清理可能已部分加载的volumes
                    if (nv && nv.volumes) {
                        nv.clearVolumes();
                    }
                    throw loadError;
                }
                let orientationVisible = true
                nv.setIsOrientationTextVisible(orientationVisible)
                // 设置鼠标事件配置  没配置成功，不知道哪个优先级比较高，和setSliceType冲突了？


                if (nv.volumes.length > 0) {
                    const volume = nv.volumes[0];
                    setDataRange({ min: volume.global_min, max: volume.global_max });
                    setIntensityMin(volume.cal_min);
                    setIntensityMax(volume.cal_max);

                    // 配置 3D 渲染以显示 mask
                    if (nv.volumes.length > 1) {
                        // 如果有 mask，配置 3D 渲染参数
                        for (let i = 1; i < nv.volumes.length; i++) {
                            const maskVolume = nv.volumes[i];
                            // 确保 mask 在 3D 视图中可见
                            // 保留从 props 传入的 colorMap
                            // maskVolume.opacity = 0.5; // 不再覆盖透明度
                            maskVolume.cal_min = 0.1; // 降低阈值以显示更多 mask 区域
                            maskVolume.cal_max = 1.0;

                            console.log(`ImageViewer3D - 配置 mask ${i}:`, {
                                opacity: maskVolume.opacity,
                                cal_min: maskVolume.cal_min,
                                cal_max: maskVolume.cal_max,
                                colorMap: maskVolume.colorMap
                            });
                        }
                    }

                    // 强制重绘以确保mask正确显示
                    nv.updateGLVolume();

                    // 设置 3D 渲染模式以更好地显示 mask
                    nv.setRenderAzimuthElevation(120, 10); // 设置一个好的 3D 视角
                }
            } catch (err) {
                console.error("An error occurred during setup:", err);
                setError("加载模型失败。");
            } finally {
                setIsLoading(false);
            }
        }

        setupNiivue();

        return () => {
            const canvas = canvasRef.current;
            if (canvas) {
                canvas.removeEventListener('contextmenu', handleContextMenu);
            }
            if (nvRef.current) {
                console.log('ImageViewer3D - 清理 Niivue 实例');
                nvRef.current.cleanup();
                nvRef.current = null;
            }
        };
    }, [imageUrl, maskUrls]);

    // Effect 2: 更新图像灰度
    useEffect(() => {
        if (!nvRef.current || nvRef.current.volumes.length === 0 || isLoading) return;
        const volume = nvRef.current.volumes[0];
        volume.cal_min = Math.min(intensityMin, intensityMax);
        volume.cal_max = Math.max(intensityMin, intensityMax);
        // 更新灰度后，也需要重绘
        nvRef.current.updateGLVolume();
    }, [intensityMin, intensityMax, isLoading]);

    // Effect 3: 更新滚轮和右键行为
    useEffect(() => {
        // 确保 nvRef 和 canvasRef 都已准备好
        if (!nvRef.current || !canvasRef.current) {
            return;
        }
        const nv = nvRef.current;
        const canvas = canvasRef.current;

        // 1. 根据 useWheelForZoom 的值，设置鼠标左键的拖拽模式
        if (useWheelForZoom) {
            // 模式1: 左键拖拽 = 平移
            nv.opts.dragMode = nv.dragModes.pan;
        } else {
            // 模式2: 左键拖拽 = 调节灰度 (窗宽窗位)
            nv.opts.dragMode = nv.dragModes.windowing;
        }


        return () => {// 清理工作 (如果需要)
        };

    }, [useWheelForZoom, nvRef, canvasRef]);

    // Effect 4: 监听切片位置变化
    useEffect(() => {
        if (!nvRef.current || !canvasRef.current) return;

        const nv = nvRef.current;
        const canvas = canvasRef.current;

        // 获取当前切片索引的函数
        const updateSliceIndices = () => {
            if (!nv || !nv.volumes || nv.volumes.length === 0) return;

            try {
                const volume = nv.volumes[0];
                if (!volume || !volume.dims) return;

                // 获取当前切片索引 - 使用多种方法确保准确性
                const dims = volume.dims;
                if (!dims || dims.length < 4) return;

                // // 调试：打印 Niivue scene 对象的可用属性
                // console.log('Niivue scene 对象调试:', {
                //     scene: nv.scene,
                //     sceneKeys: nv.scene ? Object.keys(nv.scene) : 'scene is null',
                //     crosshairPos: nv.scene?.crosshairPos,
                //     slicePos: nv.scene?.slicePos,
                //     sliceMM: nv.scene?.sliceMM,
                //     volScaleMultiplier: nv.scene?.volScaleMultiplier
                // });

                // 方法1: 尝试使用 Niivue 的切片位置属性
                let axialSlice, sagittalSlice, coronalSlice;

                // 检查是否有 sliceMM 属性（毫米坐标）
                if (nv.scene && nv.scene.sliceMM && Array.isArray(nv.scene.sliceMM)) {
                    const mm = nv.scene.sliceMM;
                    // 使用 mm2vox 转换毫米坐标到体素坐标
                    try {
                        if (typeof nv.mm2vox === 'function') {
                            const voxelCoords = nv.mm2vox(mm, volume);
                            if (voxelCoords && voxelCoords.length >= 3) {
                                axialSlice = Math.round(voxelCoords[2]);
                                sagittalSlice = Math.round(voxelCoords[0]);
                                coronalSlice = Math.round(voxelCoords[1]);
                                console.log('使用 sliceMM + mm2vox 方法:', { mm, voxelCoords, calculated: { axialSlice, sagittalSlice, coronalSlice } });
                            }
                        }
                    } catch (e) {
                        console.log('sliceMM + mm2vox 转换失败:', e);
                    }
                }
                // 检查是否有 slicePos 属性（归一化坐标 0-1）
                else if (nv.scene && nv.scene.slicePos && Array.isArray(nv.scene.slicePos)) {
                    const pos = nv.scene.slicePos;
                    axialSlice = Math.round(pos[2] * (dims[3] - 1));
                    sagittalSlice = Math.round(pos[0] * (dims[1] - 1));
                    coronalSlice = Math.round(pos[1] * (dims[2] - 1));
                    // console.log('使用 slicePos 方法:', { pos, dims, calculated: { axialSlice, sagittalSlice, coronalSlice } });
                }
                // 方法2: 尝试使用 crosshairPos 和 mm2vox
                else {
                    const mm = nv.scene.crosshairPos;
                    if (mm && mm.length >= 3) {

                        // 方法3: 如果上述方法都失败，假设 crosshairPos 是归一化坐标
                        if (axialSlice === undefined) {
                            // 检查坐标范围来判断是否为归一化坐标
                            const isNormalized = mm.every(coord => coord >= 0 && coord <= 1);
                            if (isNormalized) {
                                axialSlice = Math.round(mm[2] * (dims[3] - 1));
                                sagittalSlice = Math.round(mm[0] * (dims[1] - 1));
                                coronalSlice = Math.round(mm[1] * (dims[2] - 1));
                                // console.log('使用归一化坐标方法:', { mm, dims, calculated: { axialSlice, sagittalSlice, coronalSlice } });
                            } else {
                                // 假设是世界坐标，需要转换
                                axialSlice = Math.round(mm[2]);
                                sagittalSlice = Math.round(mm[0]);
                                coronalSlice = Math.round(mm[1]);
                                console.log('使用世界坐标方法:', { mm, calculated: { axialSlice, sagittalSlice, coronalSlice } });
                            }
                        }
                    }
                }

                // 确保索引在有效范围内并更新状态
                if (axialSlice !== undefined && sagittalSlice !== undefined && coronalSlice !== undefined) {
                    const validSlices = {
                        axial: Math.max(0, Math.min(axialSlice, dims[3] - 1)),
                        sagittal: Math.max(0, Math.min(sagittalSlice, dims[1] - 1)),
                        coronal: Math.max(0, Math.min(coronalSlice, dims[2] - 1))
                    };

                    setSliceIndices(validSlices);

                    // console.log('最终切片索引:', {
                    //     dims: dims,
                    //     maxSlices: { axial: dims[3] - 1, sagittal: dims[1] - 1, coronal: dims[2] - 1 },
                    //     validSlices: validSlices
                    // });
                }
            } catch (error) {
                console.log('获取切片索引时出错:', error);
            }
        };

        // 监听各种事件来更新切片位置
        const handleInteraction = (event) => {
            // 等待一小段时间让 Niivue 更新位置
            setTimeout(updateSliceIndices, 50);
        };

        // 添加多种事件监听器
        canvas.addEventListener('click', handleInteraction);
        canvas.addEventListener('wheel', handleInteraction);
        canvas.addEventListener('mouseup', handleInteraction);
        canvas.addEventListener('mousemove', handleInteraction);
        canvas.addEventListener('keydown', handleInteraction);

        // 尝试使用 Niivue 的内置事件系统（如果可用）
        if (nv.onLocationChange && typeof nv.onLocationChange === 'function') {
            nv.onLocationChange = updateSliceIndices;
            console.log('已设置 Niivue onLocationChange 回调');
        }

        // 设置更频繁的更新（每100ms更新一次）
        const intervalId = setInterval(updateSliceIndices, 100);

        // 初始更新
        setTimeout(updateSliceIndices, 100);

        return () => {
            canvas.removeEventListener('click', handleInteraction);
            canvas.removeEventListener('wheel', handleInteraction);
            canvas.removeEventListener('mouseup', handleInteraction);
            canvas.removeEventListener('mousemove', handleInteraction);
            canvas.removeEventListener('keydown', handleInteraction);
            clearInterval(intervalId);
        };
    }, []);

    // 重置灰度调节到默认值
    const resetIntensity = () => {
        if (nvRef.current && nvRef.current.volumes.length > 0) {
            const volume = nvRef.current.volumes[0];
            setIntensityMin(volume.global_min);
            setIntensityMax(volume.global_max);
        }
    };

    // --- JSX (渲染) ---
    return (
        <div className="flex flex-col flex-1">
            <div className="bg-gray-100 p-3 rounded-md mb-4 border border-gray-200 space-y-3">
                <div>
                    <h4 className="text-sm font-semibold mb-2 text-gray-800">交互控制</h4>
                    <div className="text-xs text-gray-600 mb-2 space-y-1">
                        <div className="font-mono bg-gray-50 p-2 rounded">
                            {nvRef.current && nvRef.current.volumes && nvRef.current.volumes.length > 0 ? (
                                <>
                                    <div>轴向切片 (Axial): {sliceIndices.axial} / {nvRef.current.volumes[0].dims[3] - 1}</div>
                                    <div>矢状切片 (Sagittal): {sliceIndices.sagittal} / {nvRef.current.volumes[0].dims[1] - 1}</div>
                                    <div>冠状切片 (Coronal): {sliceIndices.coronal} / {nvRef.current.volumes[0].dims[2] - 1}</div>
                                    {/* <div className="text-xs text-gray-500 mt-1">
                                        体积维度: {nvRef.current.volumes[0].dims.join(' × ')}
                                    </div> */}
                                </>
                            ) : (
                                <>
                                    <div>轴向切片 (Axial): {sliceIndices.axial}</div>
                                    <div>矢状切片 (Sagittal): {sliceIndices.sagittal}</div>
                                    <div>冠状切片 (Coronal): {sliceIndices.coronal}</div>
                                </>
                            )}
                        </div>
                    </div>
                    <label className="flex items-center text-xs text-gray-700">
                        <input type="checkbox" checked={useWheelForZoom} onChange={(e) => setUseWheelForZoom(e.target.checked)} className="mr-2" />
                        使用模式2 (取消后为模式1)
                    </label>
                </div>
                <div>
                    <div className="flex justify-between items-center mb-2">
                        <h4 className="text-sm font-semibold text-gray-800">图像灰度调节</h4>
                        <button
                            onClick={resetIntensity}
                            className="px-2 py-1 text-xs bg-red-500 text-white rounded hover:bg-red-600"
                        >
                            重置
                        </button>
                    </div>
                    <div className="grid grid-cols-2 gap-x-4">
                        <div>
                            <label htmlFor="min-slider" className="text-xs text-gray-600">Min: {Math.round(intensityMin)}</label>
                            <input id="min-slider" type="range" min={dataRange.min} max={dataRange.max} value={intensityMin} onChange={(e) => setIntensityMin(parseFloat(e.target.value))} className="w-full" disabled={isLoading || error} />
                        </div>
                        <div>
                            <label htmlFor="max-slider" className="text-xs text-gray-600">Max: {Math.round(intensityMax)}</label>
                            <input id="max-slider" type="range" min={dataRange.min} max={dataRange.max} value={intensityMax} onChange={(e) => setIntensityMax(parseFloat(e.target.value))} className="w-full" disabled={isLoading || error} />
                        </div>
                    </div>
                </div>
            </div>

            <div className="border border-gray-300 rounded-lg overflow-hidden bg-gray-900 w-full relative" style={{ height: '680px' }}>
                {isLoading && (<div className="absolute inset-0 flex items-center justify-center text-white z-10">{imageName ? `正在加载: ${imageName}` : '...'}</div>)}
                {error && !isLoading && (<div className="absolute inset-0 flex items-center justify-center text-red-400 z-10">{error}</div>)}
                <canvas ref={canvasRef} style={{ visibility: isLoading || !imageUrl ? 'hidden' : 'visible' }} className="w-full h-full block" />
            </div>
        </div>
    );
}

// 父组件 (保持不变)
export default function ImageViewer3D({ imageUrl, imageName, maskUrls = [] }) {
    return (
        <div className="space-y-4">
            <h3 className="text-lg font-semibold text-gray-900">3D体积渲染查看器</h3>
            <div className="flex">
                <SingleViewer3D imageUrl={imageUrl} imageName={imageName} maskUrls={maskUrls} />
            </div>
            <div className="text-sm text-gray-600 bg-blue-50 p-3 rounded-lg">
                <strong>交互说明：</strong>
                <ul className="list-disc list-inside mt-1">
                    <li>
                        <b>切片多视图窗口:</b>
                        <ul className="list-none pl-5 mt-1 space-y-1">
                            <li>
                                <span className="font-semibold text-blue-700">模式1:</span>
                                <ul className="list-['-_'] list-inside pl-2">
                                    <li>滚轮 = 切换显示切片</li>
                                </ul>
                            </li>
                            <li>
                                <span className="font-semibold text-green-700">模式2:</span>
                                <ul className="list-['-_'] list-inside pl-2">
                                    <li>滚轮 = 缩放视图</li>
                                    <li>右键拖拽 = 平移视图</li>
                                </ul>
                            </li>
                            <li>
                                <span className="font-semibold">通用操作:</span>
                                <ul className="list-['-_'] list-inside pl-2">
                                    <li>左键单击 = 移动十字准星 (定位)</li>
                                </ul>
                            </li>
                        </ul>
                    </li>
                    <li className="mt-2">
                        <b>体积渲染窗口：</b>
                        <ul className="list-['-_'] list-inside pl-5">
                            <li>滚轮 = 缩放显示体积</li>
                            <li>左键拖拽 = 旋转体积</li>
                        </ul>
                    </li>
                </ul>
            </div>
        </div>
    );
}